fn main() {
  // basic data type define
  let _x: i128 = 0x01_i128 << 127;
  println!("i128 = {}", _x);
  let _x: i128 = Default::default();
  println!("i128 default ={}", _x);
  let _x: i128 = i128::min_value();
  println!("i128 max = {}", _x);
  let _x: i128 = i128::max_value();
  println!("i128 min = {}", _x);
  // function
  fn add_one(x: i32) -> i32 {
    x + 1
  };
  let my_func: fn(i32) -> i32 = add_one;

  println!("add_one = {}", my_func(1));
  // closure
  let my_double = |x: i32| x * 2;
  println!("double closure = {}", my_double(2));
  // tuple
  let (x, y) = (12, "hello");
  println!("tuple x ={}, y ={}", x, y);
  // struct
  struct Point(f32, f32);

  let point = Point(1.2_f32, 1.3_f32);
  println!("point x = {} point y = {}", point.0, point.1);

  struct Point3D {
    px: f32,
    py: f32,
    pz: f32,
  };

  let point_3d = Point3D {
    px: 1.1_f32,
    py: 1.2_f32,
    pz: 1.3_f32,
  };

  println!(
    "point x ={}, y ={}, z={}",
    point_3d.px, point_3d.py, point_3d.pz
  );
  // enum
  enum Status {
    OK,
    ERROR,
  }

  let status = Status::OK;

  match status {
    Status::OK => {
      println!("status OK");
    }
    Status::ERROR => {
      println!("status ERROR")
    }
  }
  // union
  union MyUnion {
    f1: i32,
    f2: f32,
  }
  let mut u = MyUnion { f1: 1_i32 };

  unsafe {
    println!("before union v1 ={} ,show union_v2 ={}", u.f1, u.f2);
    u.f1 = 2_i32;
    u.f2 = 1.2_f32;
    println!("before union v1 ={} ,show union_v2 ={}", u.f1, u.f2);
  }
}
